
#include "particle.h"


Particle::Particle()
{
}


void Particle::setNeuralNetwork(const NeuralNetwork& ann)
{
   m_ann = ann;
}

void Particle::setX( float x, int d )
{
//    if( d > m_ann.synapseCount() || d < 0 ) return;
   
   m_ann.synapseByIndex( d )->setWeight( x );
}

void Particle::setV( float v, int d )
{
   for( int i = m_v.size();i<=d;i++ ) m_v.append( 0.0f ); // allocate memory if needed
   
   m_v[d] = v; // FIXME possible segmentation fault (i<=d)
}

void Particle::setPbest( float best )
{
  m_pbest = best;
}

void Particle::setPbestx( float x, int d )
{
   for( int i = m_pbestx.size();i<=d;i++ ) m_pbestx.append( 0.0f ); // allocate memory if needed
   
   m_pbestx[d] = x; // FIXME possible segmentation fault (i<=d)
}



float Particle::fitness(const QList< QList< float > > &inputList, const QList< QList< float > > &targetList)
{
   if( inputList.size() != targetList.size() ) return -1;
   
   float result = 0;
   
   int inputListSize = inputList.size();
   for( int i = 0;i<inputListSize;i++ )
   {
//       QList< float > &input = inputList[i];
//       QList< float > &target = targetList[i];
      
      result += fitness( inputList[i], targetList[i] );
   }
   
   return result;
}

float Particle::fitness(const QList< float > &input, const QList< float > &target)
{
   QList< float > output = m_ann.output( input );
   QList< float > error;
   
   int min = output.size();
   if( min > target.size() ) min = target.size();
   // prevent possible size difference errors
   
   for( int i = 0;i<min;i++ )
   {
      error.append( target[i] - output[i] );
   }
   
   return fitness( error );
}

float Particle::fitness(const QList< float > &error)
{
   float result = 0;
   foreach( float v, error )
   {
      result += pow( v, 2.0 );
   }
   return result;
}




int Particle::dimension()
{
   return m_ann.synapseCount();
}

float Particle::x( int d )
{
//    if( d > m_ann.synapseCount() || d < 0 ) return 0.0f;
   
   return m_ann.synapseByIndex( d )->weight();
}

float Particle::v( int d )
{
   if( m_v.size() <= d || d < 0 ) return 0.0f;
   return m_v[d];
}

float Particle::pbest()
{
  return m_pbest;
}

float Particle::pbestx( int d )
{
   if( m_pbestx.size() <= d || d < 0 ) return 0.0f;
   return m_pbestx[d];
}






Particle::~Particle()
{
}
